/*
<license>
Copyright (c) 2008, Chris Venter <chris.venter@gmail.com>
All rights reserved.

This file is part of quicktag <http://code.google.com/p/quicktag/>

quicktag is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

quicktag is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this code.
If not, see <http://www.gnu.org/licenses/>.
</license>
*/
#include "quicktag.h"

#include <string.h>

#include <iostream>

#include <generik/tracing.h>

/*
Picture* Picture_Allocate()
{
    Picture* pic = (Picture*)g_malloc0(sizeof(Picture));
    return pic;
}
*/

static GHashTable *encodings;

static gboolean
check_locale (const char *locale)
{
    GIConv cd = g_iconv_open ("UTF-8", locale);
    if ((GIConv)-1 == cd)
        return FALSE;
    g_iconv_close (cd);
    return TRUE;
}

/* stolen from gnome-desktop-item.c */
static void
insert_locales (GHashTable *encodings, const char *enc, ...)
{
    va_list args;
    char *s;

    va_start (args, enc);
    for (;;)
    {
        s = va_arg (args, char *);
        if (s == NULL)
            break;
        g_hash_table_insert (encodings, s, (void*)enc);
    }
    va_end (args);
}

/* stolen from gnome-desktop-item.c */
/* make a standard conversion table from the desktop standard spec */
void
Charset_Insert_Locales_Init (void)
{
    encodings = g_hash_table_new (g_str_hash, g_str_equal);

    /* "C" is plain ascii */
    insert_locales (encodings, "ASCII", "C", NULL);
#if WIN32
    insert_locales (encodings, "windows-1256", "ar", NULL); // 2006.12.31 - For testing with Arabic
#else
    insert_locales (encodings, "ISO-8859-6", "ar", NULL);
#endif
    insert_locales (encodings, "ARMSCII-8", "by", NULL);
    insert_locales (encodings, "BIG5", "zh_TW", NULL);
    insert_locales (encodings, "CP1251", "be", "bg", NULL);
    if (check_locale ("EUC-CN")) {
        insert_locales (encodings, "EUC-CN", "zh_CN", NULL);
    } else {
        insert_locales (encodings, "GB2312", "zh_CN", NULL);
    }
    insert_locales (encodings, "EUC-JP", "ja", NULL);
    insert_locales (encodings, "EUC-KR", "ko", NULL);
    /*insert_locales (encodings, "GEORGIAN-ACADEMY", NULL);*/
    insert_locales (encodings, "GEORGIAN-PS", "ka", NULL);
    insert_locales (encodings, "ISO-8859-1", "br", "ca", "da", "de", "en", "es", "eu", "fi", "fr", "gl", "it", "nl", "wa", "nb", "nn", "pt", "pt", "sv", NULL);
#if WIN32
    insert_locales (encodings, "windows-1250", "cs", "hr", "hu", "pl", "ro", "sk", "sl", "sq", "sr", NULL);
#else
    insert_locales (encodings, "ISO-8859-2", "cs", "hr", "hu", "pl", "ro", "sk", "sl", "sq", "sr", NULL);
#endif
    insert_locales (encodings, "ISO-8859-3", "eo", NULL);
    insert_locales (encodings, "ISO-8859-5", "mk", "sp", NULL);
#if WIN32
    insert_locales (encodings, "windows-1253", "el", NULL);
#else
    insert_locales (encodings, "ISO-8859-7", "el", NULL);
#endif
#if WIN32
    insert_locales (encodings, "windows-1254", "tr", NULL);
#else
    insert_locales (encodings, "ISO-8859-9", "tr", NULL);
#endif
    insert_locales (encodings, "ISO-8859-13", "lt", "lv", "mi", NULL);
    insert_locales (encodings, "ISO-8859-14", "ga", "cy", NULL);
    insert_locales (encodings, "ISO-8859-15", "et", NULL);
#if WIN32
    insert_locales (encodings, "windows-1251", "ru", NULL);
#else
    insert_locales (encodings, "KOI8-R", "ru", NULL);
#endif
    insert_locales (encodings, "KOI8-U", "uk", NULL);
    if (check_locale ("TCVN-5712")) {
        insert_locales (encodings, "TCVN-5712", "vi", NULL);
    } else {
        insert_locales (encodings, "TCVN", "vi", NULL);
    }
    insert_locales (encodings, "TIS-620", "th", NULL);
#if WIN32
    insert_locales (encodings, "windows-1255", "he", NULL);
#endif
    /*insert_locales (encodings, "VISCII", NULL);*/
}

void
Charset_Insert_Locales_Destroy (void)
{
    g_hash_table_destroy (encodings);
}

/* stolen from gnome-desktop-item.c */
const char *
get_encoding_from_locale (const char *locale)
{
    char lang[3];
    const char *encoding;

    if (locale == NULL)
        return NULL;

    /* if locale includes encoding, use it *//*
    encoding = strchr (locale, '.');
    if (encoding != NULL) {
        return encoding+1;
    }*/
    /* if locale includes encoding (that isn't UTF-8), use it */
    encoding = strchr (locale, '.');
    if (encoding != NULL && strncmp (encoding, ".UTF-8", 6)) {
        return encoding+1;
    }

    /* first try the entire locale (at this point ll_CC) */
    encoding = (const char*)g_hash_table_lookup (encodings, locale);
    if (encoding != NULL)
        return encoding;

    /* Try just the language */
    strncpy (lang, locale, 2);
    lang[2] = '\0';
    return (const char*)g_hash_table_lookup(encodings, lang);
}

const gchar *get_locale (void)
{
    const gchar *loc;
    
    if (   (loc = g_getenv("LC_ALL"))    &&     *loc    )
        return loc;

    else if ((loc = g_getenv((gchar*)"LC_CTYPE")) && *loc)
        return loc;

    else if ((loc = g_getenv((gchar*)"LANG")) && *loc)
        return loc;

     else
         return NULL;
}

#include "id3_tag.h"
#include "ogg_tag.h"
#include "mp4_tag.h"
#include "asf_tag.h"

gchar *Try_To_Validate_Utf8_String (const gchar *string)
{
    gchar *ret = NULL;
    GError *error = NULL;

    if (!string)
        return NULL;

    if (g_utf8_validate(string, -1, NULL))
    {
        // String already in UTF-8
        ret = g_strdup(string);
    }else
    {
        const gchar *char_encoding;

        // Get encoding associated to the locale without using UTF-8 (ex , if LANG=fr_FR.UTF-8 it will return ISO-8859-1)
        char_encoding = get_encoding_from_locale(get_locale());
        if (char_encoding)
        {
            //g_print("> char_encoding: %s\n",char_encoding);
            error = NULL;
            ret = g_convert(string, -1, "UTF-8", char_encoding, NULL, NULL, &error);
        }

        if (!ret)
        {
            // Failing that, try ISO-8859-1
            error = NULL;
            ret = g_convert(string, -1, "UTF-8", "ISO-8859-1", NULL, NULL, &error);
        }

        if (!ret)
        {
            gchar *escaped_str = g_strescape(string, NULL);
            //Log_Print(LOG_ERROR,_("The string '%s' couldn't be converted into UTF-8 (%s)."),
            //            escaped_str, error && error->message ? error->message : _("Invalid UTF-8"));
            //std::cerr<<"The string '"<<escaped_str<<"' could not be converted into UTF-8 (";
            //std::cerr<<(error && error->message ? error->message : _("Invalid UTF-8"));
            //std::cerr<<")"<<std::endl;
            g_clear_error(&error);

            ret = escaped_str;
        }
    }

    return ret;
}

namespace quicktag
{
	
	int read_file(const std::string& path, quicktag::tags& tags)
	{
		GENERIK_TRACER;
		
		if (!quicktag::read_id3(path, tags))
		{
			GENERIK_TRACE("found a file with id3 tags: "<<path);
			return READVAL_OK;
		}
		if (!quicktag::read_asf(path, tags))
		{
			GENERIK_TRACE("found a file with asf tags: "<<path);
			return READVAL_OK;
		}
		
		if (!quicktag::read_mp4(path, tags))
		{
			GENERIK_TRACE("found a file with mp4 tags: "<<path);
			return READVAL_OK;
		}
		
		if (!quicktag::read_ogg(path, tags))
		{
			GENERIK_TRACE("found a file with ogg tags: "<<path);
			return READVAL_OK;
		}
		
		GENERIK_TRACE("file is broken/does not contain tags: "<<path);
		// indicate that no tags are not ok
		tags.ok = false;
		
		return READVAL_UNKNOWN;
	}
	
}


























